from django.shortcuts import render

from django.views.generic import View

from django.http import JsonResponse

from goods.models import GoodsSKU

from django_redis import get_redis_connection

import json
# Create your views here.

'''删除购物车'''
class DeleteCartView(View):

    def post(self, request):
        # 接收参数：sku_id
        sku_id = request.POST.get('sku_id')

        # 校验参数：not，判断是否为空
        if not sku_id:
            return JsonResponse({'code': 1, 'message': '参数错误'})

        # 判断用户是否登录
        if request.user.is_authenticated():
            # 如果用户登陆，删除redis中购物车数据
            redis_conn = get_redis_connection('default')

            user_id = request.user.id

            redis_conn.hdel('cart_%s' % user_id, sku_id)

        else:
            # 如果用户未登陆，删除cookie中购物车数据
            cart_json = request.COOKIES.get('cart')
            if cart_json is not None:
                cart_dict = json.loads(cart_json)

                if sku_id in cart_dict:
                    del cart_dict[sku_id]

                # 相应计入cookie:
                response = JsonResponse({'code': 0, 'message': '删除成功'})

                new_cart_json = json.dumps(cart_dict)
                response.set_cookie('cart', new_cart_json)

                return response

        return JsonResponse({'code': 0, 'message': '删除成功'})




'''更新购物车'''
class UpdateCartView(View):

    def post(self, request):
        # 获取参数：sku_id, count
        sku_id = request.POST.get('sku_id')
        count = request.POST.get('count')

        # 校验参数all()
        if not all([sku_id, count]):
            return JsonResponse({'code': 1, 'message': '参数不完整'})

        # 判断商品是否存在
        try:
            sku = GoodsSKU.objects.get(id=sku_id)
        except GoodsSKU.DoesNotExist:
            return JsonResponse({'code': 2, 'message': '商品不存在'})

        # 判断count是否是整数
        try:
            count = int(count)

        except Exception:
            return JsonResponse({'code': 3, 'message': '商品数量有误'})

        # 判断库存
        if count > sku.stock:
            return JsonResponse({'code': 4, 'message': '库存不足'})

        # 判断用户是否登陆
        if request.user.is_authenticated():
            # 如果用户登陆，将修改的购物车数据存储到redis中
            redis_conn = get_redis_connection('default')

            # 如果设计成幂等的，count就是最终要保存的商品的数量，不需要累加
            user_id = request.user.id
            redis_conn.hset('cart_%s' % user_id, sku_id, count)

            return JsonResponse({'code': 0, 'message': '添加购物车成功'})

        else:
            # 如果用户未登陆，将修改的购物车数据存储到cookie中
            cart_json = request.COOKIES.get('cart')

            if cart_json is not None:
                cart_dict = json.loads(cart_json)
            else:
                cart_dict = {}
            # 如果设计成幂等的，count就是最终要保存的商品的数量，不需要累加
            cart_dict[sku_id] = count

            # 字典转成json字符串
            new_cart_json = json.dumps(cart_dict)

            # 响应结果
            response = JsonResponse({'code': 0, 'message': '添加购物车成功'})

            response.set_cookie('cart', new_cart_json)

            return response







'''购物车页面'''
class CartInfoView(View):

    def get(self, request):
        # 展示购物车的页面

        '''用户登陆,redis'''
        if request.user.is_authenticated():

            redis_conn = get_redis_connection('default')

            user_id = request.user.id

            cart_dict = redis_conn.hgetall('cart_%s' % user_id)

        else:
            '''未登录, cookie'''
            cart_json = request.COOKIES.get('cart')

            if cart_json is not None:
                cart_dict = json.loads(cart_json)
            else:
                cart_dict = {}


        # 临时变量:
        skus = []

        total_sku_amount = 0

        total_count = 0

        # 遍历字典
        for sku_id, count in cart_dict.items():
            try:
                sku = GoodsSKU.objects.get(id=sku_id)
            except GoodsSKU.DoesNotExist:
                # 商品不存在,跳过,继续访问
                continue

            count = int(count)

            # 小计
            amount = sku.price * count

            # 面向对象的动态语言:动态给sku对象绑定 count 和 amount
            sku.amount = amount
            sku.count = count

            skus.append(sku)

            # 累计金额和数量
            total_sku_amount += amount
            total_count += count


        context = {

            'skus': skus,
            'total_sku_amount': total_sku_amount,
            'total_count': total_count
        }

        return render(request, 'cart.html', context)



'''实现添加购物车'''
# 登陆用户购物车数据在redis, 未登陆用户数据在cookie中
# 传入的数据:用户的id(user_id), 商品的id(sku_id), 商品的数量(count)
class AddCartView(View):
    """添加到购物车"""

    def post(self, request):
        '''用户未登陆时,数据计入到cookie中, 不是异常'''
        # 判断用户是否登陆
        # if not request.user.is_authenticated():
        #     # 用户未登录时,数据保存在cookie中
        #     return JsonResponse({'code': 1, 'message': '用户未登陆'})


        # 接收数据：user_id，sku_id，count
        # user_id = request.user.id
        sku_id = request.POST.get('sku_id')
        count = request.POST.get('count')

        # 校验参数all()是否为空
        if not all([sku_id, count]):
            return JsonResponse({'code': 2, 'message': '缺少参数'})

        # 判断商品是否存在 --- sku_id是否合法
        try:
            sku = GoodsSKU.objects.get(id=sku_id)
        except GoodsSKU.DoesNotExist:
            return JsonResponse({'code': 3, 'message': '商品的id有误'})

        # 判断count是否是整数
        try:
            count = int(count)
        except Exception:
            return JsonResponse({'code': 4, 'message': '商品的数量有误'})
        '''无论是否登陆都要获取sku_id 和 count, 在校验参数
            校验完成后再判断是否用户登陆
        '''

        # # 判断库存(sku.stock)
        # if count > sku.stock:
        #     return JsonResponse({'code': 5, 'message': '库存不足'})




        '''将商品的信息计入到redis中时,才需要判断用户登陆'''
        if request.user.is_authenticated():

            # 登陆用户,获取用户的id
            user_id = request.user.id

            # 操作redis数据库存储商品到购物车 --- 加入购物车,数据存储在redis
            # 创建redis_conn,与redis形成链接
            redis_conn = get_redis_connection('default')

            '''判断要添加的数据是否在redis中存在:
                如果应经存在,做商品数量的累加, 如果不存在, 给商品赋值'''
            # 商品在redis中存储的的形式是hash类型: key filed value   (cart_useid, sku_id, count)
            # 获取添加到购物车中的商品是否已经存在: 用sku_id获取数量
            origin_count = redis_conn.hget('cart_%s' % user_id, sku_id)

            if origin_count is not None:
                # 要添加的商品已经存在:origin_count 是bytes类型 --- 转成int类型
                count += int(origin_count)

            # 判断库存(sku.stock) 累加后再次判断是否超出库存
            if count > sku.stock:
                return JsonResponse({'code': 5, 'message': '库存不足'})

            '''   # 数据存储到redis中
                redis_conn.hset('cart_%s' % user_id, sku_id, count)
            else:
                # 添加的商品在redis中没有,给商品赋值
                redis_conn.hset('cart_%s' % user_id, sku_id, count)
            '''
            # 简化代码
            redis_conn.hset('cart_%s' % user_id, sku_id, count)

            # 配合前端展示购物车的总数据, 需要在响应json之前,查询购物车数据
            cart_num = 0

            cart_dict = redis_conn.hgetall('cart_%s' % user_id)

            for val in cart_dict.values():
                cart_num += int(val)
                #val ---> count 是bytes类型 需要转换为int

            # json方式响应添加购物车结果
            return JsonResponse({'code': 0, 'message': '购物车添加成功', 'cart_num': cart_num})

        else:
            '''用户没有登陆时, 购物车的数据就保存在cookie中: cart_json = "{'sku_id1':1, 'sku_id2':2}"'''
            # 从cookie中获取购物车的信息, json字符串购物车数据
            cart_json = request.COOKIES.get('cart')

            # 判断以前是否有购物车信息
            if cart_json is not None:
                # 将json字符串转换成字典
                cart_dict = json.loads(cart_json)

            else:
                # 用户可能从没有操作过购物车, 那么赋值为空
                cart_dict = {}

            '''判断添加的购物车数据以前是否存在,存在就进行累加, 不存在就保存在cookie中'''
            if sku_id in cart_dict:
                # 以前有相同记录,累加count origin_count是int类型
                origin_count = cart_dict[sku_id]

                count += origin_count


            # 累加后要判断库存
            if count > sku.stock:
                return JsonResponse({'code': 5, 'message': '库存不足'})


            '''
                # 新的数量添加到cookie中
                cart_dict[sku_id] = count
            else:
                # 以前没有相同记录,添加
                cart_dict[sku_id] = count
            '''
            # 简化代码
            cart_dict[sku_id] = count

            '''将信息写入cookie response.set_cookie(key, string)'''

            # 为了配合前端页面,展示最终的购物车数据的总数,需要在响应json之前,查询购物车数据
            cart_num = 0

            for val in cart_dict.values():
                # val就是count,是int类型
                cart_num += val


            # 将json字典转换为json字符串
            new_cart_json = json.dumps(cart_dict)

            # 计入到cookie中
            response = JsonResponse({'code': 0, 'message': '购物车添加成功', 'cart_num': cart_num})

            response.set_cookie('cart', new_cart_json)

            return response






        '''
        response = HttpResponse
        response = JsonResponse
        response = render
        response = redirect
        '''











